<?php defined('SYSPATH') or die('No direct script access.');

class Model_CouponParser_Admitad extends Model_CouponParser_Abstract
{ 
    protected $filename = null;         // Название файла
    protected $handler = null;          // Дескриптор файла
    protected $charset = null;          // Кодировка входного файла
    
    /**
    * Парсим товары магазина
    * 
    * @param Model_Shop $shop
    */
    public function parse($url)
    {  
        //$this->filename = APPPATH.'../data/tmp/admitad_coupons.xml';  
        $this->filename = APPPATH.'../data/tmp/'.time().'_'.mt_rand(1, 1000).'.xml';
        $this->_download_file($url, $this->filename);
        $n = $this->_parse();
        unlink($this->filename); 
        
        return $n;
    }  
    
    protected function _get_current_coupon_id()
    {
        $current_id = DB::select(array(DB::expr('MAX(id)'), 'max'))
            ->from('coupons')
            ->execute()
            ->as_array();
        $current_id = $current_id[0]['max'];
        return $current_id;
    }   
    
    protected function _parse()
    {
        $this->_open_file();   
        $this->_detect_charset();
        
        // TODO types
        
        // TODO categories
        
        // Добавляем магазины
        while ($shop_data = $this->_get_shop()) {
            $shop_id   = $this->_get_shop_id($shop_data);
            $shop_name = $this->_get_shop_name($shop_data);
            $shop_url  = Model_Main::translit($shop_name);
            $shop_url  = str_replace('-amp-', '-and-', $shop_url);
            
            try {
                //echo $shop_id.' -- '.$shop_name.' -- '.$shop_url."\n";

                DB::insert('shops', array('id', 'name', 'url'))
                        ->values(array($shop_id, $shop_name, $shop_url))->execute();
            } catch (Database_Exception $e) {
                if (strstr($e->getMessage(), 'Duplicate entry') !== false) {
                    continue;
                }
                die($e->getMessage());
            }       
        }
            
        // Добавляем купоны
        $n = 0;
        $current_id = $this->_get_current_coupon_id();
        
        while ($coupon_data = $this->_get_coupon()) { 
            $shop_id    = $this->_get_coupon_shop_id($coupon_data);
            $partner    = 'admitad';
            $source_id  = $this->_get_coupon_id($coupon_data);
            $name       = $this->_get_coupon_name($coupon_data);
            $promocode  = $this->_get_coupon_promocode($coupon_data);
            $promolink  = $this->_get_coupon_promolink($coupon_data);
            $gotolink   = $this->_get_coupon_gotolink($coupon_data);
            $logo       = $this->_get_coupon_logo($coupon_data);
            $description = $this->_get_coupon_description($coupon_data);
            $start_date = $this->_get_coupon_start_date($coupon_data);
            $end_date   = $this->_get_coupon_end_date($coupon_data);
                            
            //$types      = $this->_get_coupon_types($coupon_data);
            //$categories = $this->_get_coupon_categories($coupon_data);
            
            $shop = ORM::factory('shop', $shop_id);
            if (!$shop->image) {
                sleep(1);
                $dir = APPPATH.'../media/uploads/shops/';
                   
                $data = file_get_contents($logo);
                $f = fopen($dir.'/logo-'.$shop->url.'.jpg', 'w+');
                fputs($f, $data);
                fclose($f);
                
                $shop->image = 1;
                $shop->save();
            }
                 
            try { 
                $current_id++;
                           
                $insert = DB::insert('coupons', array('id', 'shop_id', 'partner', 'source_id', 'name', 'promocode', 'promolink', 'gotolink', 'logo',
                            'description', 'start_date', 'end_date'))
                                    ->values(array($current_id, $shop_id, $partner, $source_id, $name, $promocode, $promolink, $gotolink, $logo,
                            $description, $start_date, $end_date))->execute();
                            
                //$coupon_id = $insert[0];
                $n++;
            } catch (Database_Exception $e) {
                if (strstr($e->getMessage(), 'Duplicate entry') !== false) {
                    $current_id--;      // возвращаем назад идентификатор, т.к. он увеличился, но запись не вставилась
                    
                } else {
                    die($e->getMessage());
                }
            }
        }       
        $this->_close_file(); 
        return $n;     
    } 
    
    protected function _get_coupon_shop_id(&$coupon_data)
    {
        $shop_id = $this->_cut_str('<advcampaign_id>', '</advcampaign_id>', $coupon_data); 
        if ($shop_id) {
            return $shop_id;
        }
        return 0;    
    }           
    
    protected function _get_coupon_id(&$coupon_data)
    {
        return $this->_cut_str(' id="', '"', $coupon_data);  
    }
    
    protected function _get_coupon_name(&$coupon_data)
    {
        return $this->_cut_str('<name>', '</name>', $coupon_data);  
    }
    
    protected function _get_coupon_short_name(&$coupon_data)
    {
        return $this->_cut_str('<short_name>', '</short_name>', $coupon_data); 
    }

    protected function _get_coupon_promocode(&$coupon_data)
    {
        return $this->_cut_str('<promocode>', '</promocode>', $coupon_data);
    }
    
    protected function _get_coupon_promolink(&$coupon_data)
    {
        return $this->_cut_str('<promolink>', '</promolink>', $coupon_data);  
    }
    
    protected function _get_coupon_gotolink(&$coupon_data)
    {
        return $this->_cut_str('<gotolink>', '</gotolink>', $coupon_data);  
    } 
    
    protected function _get_coupon_logo(&$coupon_data)
    {
        return $this->_cut_str('<logo>', '</logo>', $coupon_data);  
    }        
      
    protected function _get_coupon_description(&$coupon_data)
    {
        return $this->_cut_str('<description>', '</description>', $coupon_data);  
    } 
    
    protected function _get_coupon_start_date(&$coupon_data)
    {
        return $this->_cut_str('<date_start>', '</date_start>', $coupon_data);  
    }  
    
    protected function _get_coupon_end_date(&$coupon_data)
    {
        return $this->_cut_str('<date_end>', '</date_end>', $coupon_data);  
    }  
    
    protected function _get_coupon_discount(&$coupon_data)
    {
        return $this->_cut_str('<discount>', '</discount>', $coupon_data);  
    } 
    
    protected function _get_coupon_types(&$coupon_data)
    {
        $types = array();
        while ($item = $this->_cut_str('<type_id>', '</type_id>', $coupon_data)) {
            $types[] = $item;
        }     
        return $types;
    }
    
    protected function _get_coupon_categories(&$coupon_data)
    {
        $categories = array();
        while ($item = $this->_cut_str('<category_id>', '</category_id>', $coupon_data)) {
            $categories[] = $item;
        }     
        return $categories;
    }  
    
    /*protected function _get_category_id(&$category_data)
    {
        $category_id = $this->_cut_str('id="', '"', $category_data);
        return $category_id;  
    }
    
    protected function _get_category_name(&$category_data)
    {
        $name = $this->_cut_str('>', '<', $category_data);
        return $this->_cut_quotes($name);  
    }
    
    protected function _get_category_parent_id(&$category_data)
    {
        $parent_id = $this->_cut_str('parentId="', '"', $category_data);
        if (!$parent_id) {
            return 0;
        }
        return $parent_id;  
    } */
    
    protected function _get_shop_id(&$shop_data)
    {
        $shop_id = $this->_cut_str('id="', '"', $shop_data); 
        return (int)$shop_id;   
    }
    
    protected function _get_shop_name($shop_data)
    {
        $name = $this->_cut_str('<name>', '</name>', $shop_data); 
        return $name;     
    }
    
    protected function _get_shop_site($shop_data)
    {
        $url = $this->_cut_str('<site>', '</site>', $shop_data); 
        return $url;     
    }
    
    protected function _open_file()
    {
        $result = $this->handler = fopen($this->filename, 'r+'); 
        if (!$result) {
            throw new Model_Exception('Не удалось открыть файл');
        }
        return $result; 
    }
    
    protected function _detect_charset()
    {
        $str = fgets($this->handler);
        $charset = $this->_cut_str(' encoding="', '"', $str);
        
        if ($charset) {
            $this->charset = mb_strtolower($charset);
        } else {
            $this->charset = 'utf-8';
        }
    }
    
    protected function _encode($str)
    {
        if ($this->charset == 'utf-8') {
            return $str;
        }
        
        return iconv($this->charset, 'utf-8', $str);
    }
    
    protected function _get_coupon()
    {
        $data = null;
        while($str = fgets($this->handler)) {              
            if (strstr($str, '<coupon ') !== false) {
                $data = $str;
                
                $str = fgets($this->handler);
                while (strstr($str, '</coupon>') === false) {
                    $data .= $str;
                    $str   = fgets($this->handler);
                }
                if (strstr($str, '</coupons>') !== false) {
                    return false;    
                }
                fseek($this->handler, -mb_strlen($str), SEEK_CUR);
                
                break;
            }
        }     
        return $this->_encode($data);
    }
    
    protected function _get_category()
    {
        $data = null;
        while($str = fgets($this->handler)) {  
            if (strstr($str, '</categories>') !== false) {
                return null;    
            }            
            if (strstr($str, '<category ') !== false) {
                $data = $str;
                
                while (strstr($str, '/category>') === false) {
                    $data .= $str;
                    $str   = fgets($this->handler);
                }
                //fseek($this->handler, -mb_strlen($str), SEEK_CUR);
                
                break;
            }
        }     
        return $this->_encode($data);
    }
    
    protected function _get_shop()
    {
        $data = null;
        while($str = fgets($this->handler)) {  
            if (strstr($str, '</advcampaigns>') !== false) {
                return null;    
            }               
            if (strstr($str, '<advcampaign ') !== false) {
                $data = $str;
                
                do {
                    $str   = fgets($this->handler);
                    $data .= $str;
                } while (strstr($str, '</advcampaign>') === false);
                //fseek($this->handler, -mb_strlen($str), SEEK_CUR);
                
                break;
            }
        }  
        return $this->_encode($data);   
    } 
    
    protected function _close_file()
    {
        if (!fclose($this->handler)) {
            throw new Model_Exception('Не удалось закрыть файл');   
        }  
        return true; 
    }
    
    protected function _cut_quotes($str)
    {
        return trim(str_replace(array('<![CDATA[', ']]>'), '', $str));    
    }
}